# _*_ coding: utf-8 _*_
"""
Time:     2024/8/30
Author:   2051261
File:     init.py
"""
import asyncio
from pathlib import Path
from typing import List

from mine.db.db_operate import db_operate
from mine.project.log import log_manager as logger
from extractor.flow.task_model import TaskModel
from extractor.flow.task_entry import TaskEntry
from extractor.const import YmlDBConst as YmlDB
from extractor.config.load import initialize_log
from extractor.config.load import read_yml
from extractor.config.load import get_default_paths
from extractor.config.load import add_scheduler_job
from extractor.config.load import add_scheduler_write_jobs
from extractor.config.check_yml import check_db_yml

semaphore = asyncio.Semaphore(30)


async def initialize_db(directory_path):
    db_configure = []
    db_files = list(directory_path.glob('**/*db.yml'))
    if not db_files:
        raise FileNotFoundError(f"No YAML files found directory: {directory_path}")

    try:
        db_contents = await asyncio.gather(*[read_yml(db_file) for db_file in db_files])
        for content in db_contents:
            db_configure.extend(content)
    except Exception as e:
        raise RuntimeError(f"Error reading database configurations: {e}")

    try:
        _ = await check_db_yml(db_configure)
    except Exception as e:
        raise ValueError(f"Database configuration validation failed: {e}")

    try:
        add_session_tasks = [
            db_operate.add_session(item[YmlDB.CONN_NAME], item) for item in db_configure
        ]
        await asyncio.gather(*add_session_tasks)
    except Exception as e:
        raise RuntimeError(f"Failed to add database session: {e}")


async def load_check_task(file_path: Path) -> List[TaskEntry]:
    is_run_tasks = []
    tasks = await read_yml(file_path)
    for task in tasks:
        task_model = TaskModel(task)
        if task_model.validate() is not None:
            logger.error(f"task configuration is invalid, file_path: {file_path}")
        if task_model.is_run:
            is_run_tasks.append(TaskEntry(task_model))
        else:
            add_scheduler_job(TaskEntry(task_model))
    return is_run_tasks


async def initialize_task(task_dir: Path) -> List[TaskEntry]:
    is_run_tasks = []
    task_path_list = list(task_dir.glob('**/task*.yml'))
    if not task_path_list:
        raise FileNotFoundError(f"No YAML task files found directory: {task_path_list}")
    result = await asyncio.gather(*[load_check_task(task_path) for task_path in task_path_list])
    for is_run_task in result:
        if is_run_task:
            is_run_tasks.extend(is_run_task)
    # 添加一个将所有任务信息定时写入文件中
    # await add_scheduler_write_jobs()
    return is_run_tasks


async def initialize_task_cli(task_list: list) -> List[TaskEntry]:
    all_task_list = []
    for item in task_list:
        task_model = TaskModel(item)
        task_model.validate()
        all_task_list.append(TaskEntry(task_model))

    return all_task_list


async def init(task_list: list | None = None) -> List[TaskEntry]:
    await initialize_log()
    task_path, db_path = await get_default_paths()
    # await initialize_db(db_path)
    # if task_list is not None:
    #     is_run_tasks = initialize_task_cli(task_list)
    # else:
    is_run_tasks = await initialize_task(task_path)
    # return is_run_tasks
